home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / inventor / noodle / NoodleSlider.c++ < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  8.6 KB  |  340 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18. |   Classes:
  19. |      NoodleSlider is a component that expands the functionality of the
  20. |      standard motif slider (they call it 'scale') widget.
  21. |
  22. |   Author(s)          : Paul Isaacs
  23. |
  24. */
  25.  
  26.  
  27.  
  28. #include "NoodleSlider.h"
  29. #include <X11/StringDefs.h>
  30. #include <Xm/Form.h>
  31. #include <Xm/Text.h>
  32. #include <Xm/Scale.h>
  33.  
  34. NoodleSlider::NoodleSlider(
  35.     Widget parent,
  36.     const char *name, 
  37.     SbBool buildInsideParent, 
  38.     int startingMin,
  39.     int startingMax)
  40.     : SoXtComponent(
  41.         parent,
  42.         name, 
  43.         buildInsideParent)
  44. {
  45.     // Build the widget!
  46.     Widget w = buildWidget( getParentWidget(), startingMin, startingMax);
  47.     setBaseWidget(w);
  48.  
  49.     valueChangedCallbacks = new SoCallbackList;
  50. }
  51.  
  52. NoodleSlider::~NoodleSlider()
  53. {
  54.     delete valueChangedCallbacks;
  55. }
  56.  
  57. Widget
  58. NoodleSlider::buildWidget( 
  59.     Widget parent,
  60.     int startingMin,
  61.     int startingMax )
  62. {
  63.     Arg wargs[10];
  64.     int  nargs;
  65.  
  66.     _form = XtCreateManagedWidget(getWidgetName(),xmFormWidgetClass,
  67.                     parent,NULL, 0);
  68.  
  69.     _value = XtCreateManagedWidget("value",xmTextWidgetClass,_form,NULL,0);
  70.  
  71.     nargs = 0;
  72.     XtSetArg(wargs[nargs],XmNorientation,    XmHORIZONTAL ); nargs++;
  73.     XtSetArg(wargs[nargs],XmNdecimalPoints,  2 ); nargs++;
  74.     XtSetArg(wargs[nargs],XmNminimum,        startingMin ); nargs++;
  75.     XtSetArg(wargs[nargs],XmNmaximum,        startingMax ); nargs++;
  76.     _slider = XtCreateManagedWidget("slider",xmScaleWidgetClass,
  77.                     _form,wargs,nargs);
  78.  
  79.     /* set the callbacks for the sub components */
  80.     XtAddCallback( _value, XmNactivateCallback,
  81.            (XtCallbackProc) &NoodleSlider::valueWidgetCallback,
  82.            (XtPointer) this );
  83.     XtAddCallback( _slider, XmNdragCallback,
  84.             (XtCallbackProc) &NoodleSlider::sliderWidgetCallback,
  85.             (XtPointer) this );
  86.     XtAddCallback( _slider, XmNvalueChangedCallback,
  87.             (XtCallbackProc) &NoodleSlider::sliderWidgetCallback,
  88.             (XtPointer) this );
  89.  
  90.     /* take care of layout within the NoodleSlider */
  91.     initLayout();
  92.  
  93.     /* initialize values throughout the NoodleSlider to be those in the scale */
  94.     /* Right now, this winds up filling the label widgets with text    */
  95.     setValue( getValue());
  96.     setMin( getMin());
  97.     setMax( getMax());
  98.     return _form;
  99. }
  100.  
  101. void
  102. NoodleSlider::initLayout()
  103. {
  104.     if (_form == NULL)
  105.     return;
  106.  
  107.     Arg wargs[10];
  108.     int  nargs;
  109.     nargs = 0;
  110.     XtSetArg(wargs[nargs],XmNborderWidth,    2 ); nargs++;
  111.     XtSetValues( _form, wargs, nargs );
  112.  
  113.     nargs = 0;
  114.     XtSetArg(wargs[nargs],XmNtopAttachment,    XmATTACH_FORM ); nargs++;
  115.     XtSetArg(wargs[nargs],XmNbottomAttachment, XmATTACH_POSITION ); nargs++;
  116.     XtSetArg(wargs[nargs],XmNbottomPosition,   100 ); nargs++;
  117.     XtSetArg(wargs[nargs],XmNleftAttachment,   XmATTACH_POSITION ); nargs++;
  118.     XtSetArg(wargs[nargs],XmNleftPosition,     0 ); nargs++;
  119.     XtSetArg(wargs[nargs],XmNrightAttachment,  XmATTACH_POSITION ); nargs++;
  120.     XtSetArg(wargs[nargs],XmNrightPosition,    30 ); nargs++;
  121.     XtSetValues( _value, wargs, nargs );
  122.  
  123.     nargs = 0;
  124.     XtSetArg(wargs[nargs],XmNtopAttachment,    XmATTACH_POSITION ); nargs++;
  125.     XtSetArg(wargs[nargs],XmNtopPosition,      0 ); nargs++;
  126.     XtSetArg(wargs[nargs],XmNbottomAttachment, XmATTACH_FORM ); nargs++;
  127.     XtSetArg(wargs[nargs],XmNleftAttachment,   XmATTACH_POSITION ); nargs++;
  128.     XtSetArg(wargs[nargs],XmNleftPosition,     30 ); nargs++;
  129.     XtSetArg(wargs[nargs],XmNrightAttachment,  XmATTACH_POSITION ); nargs++;
  130.     XtSetArg(wargs[nargs],XmNrightPosition,    100 ); nargs++;
  131.     XtSetArg(wargs[nargs],XmNtitleString,      NULL ); nargs++;
  132.     XtSetValues( _slider, wargs, nargs );
  133. }
  134.  
  135. void 
  136. NoodleSlider::setValue( float newVal )
  137. {
  138.     if ( getMin() > newVal )
  139.     setMin( newVal );
  140.     if ( getMax() < newVal )
  141.     setMax( newVal );
  142.  
  143.     /* send the value to the slider */
  144.     if (_slider) {
  145.     int motifIntValue;
  146.     motifIntValue = convertFloatToSlider( newVal );
  147.     XmScaleSetValue( _slider, motifIntValue );
  148.     }
  149.  
  150.     /* send the value to the label */
  151.     char valString[50];
  152.     sprintf( valString, "%.*f", getNumDecimals(), newVal );
  153.     XmTextSetString( _value, valString );
  154. }
  155.  
  156. void 
  157. NoodleSlider::setMin( float newVal )
  158. {
  159.     float valToUse;
  160.  
  161.     if ( newVal <= getValue() 
  162.      && newVal < getMax() )
  163.     valToUse = newVal;
  164.     else
  165.     valToUse = getMin();
  166.  
  167.     /* send the new minimum value to the slider */
  168.     if ( _slider == NULL )
  169.     return;
  170.  
  171.     Arg wargs[10];
  172.     int motifIntValue;
  173.  
  174.     motifIntValue = convertFloatToSlider( valToUse );
  175.     XtSetArg( wargs[0], XmNminimum, motifIntValue );
  176.     XtSetValues( _slider, wargs, 1 );
  177. }
  178.  
  179. void 
  180. NoodleSlider::setMax( float newVal )
  181. {
  182.     float valToUse;
  183.  
  184.     if ( newVal >= getValue() 
  185.     && newVal > getMin() )
  186.     valToUse = newVal;
  187.     else
  188.     valToUse = getMax();
  189.  
  190.     /* send the new maximum value to the slider */
  191.     if ( _slider == NULL )
  192.     return;
  193.  
  194.     Arg wargs[10];
  195.     int motifIntValue;
  196.  
  197.     motifIntValue = convertFloatToSlider( valToUse );
  198.     XtSetArg( wargs[0], XmNmaximum, motifIntValue );
  199.     XtSetValues( _slider, wargs, 1 );
  200. }
  201.  
  202. float 
  203. NoodleSlider::getValue()
  204. {
  205.     if ( _slider == NULL )
  206.     return 0.0;
  207.  
  208.     Arg wargs[10];
  209.     int motifIntValue;
  210.  
  211.     XtSetArg( wargs[0], XmNvalue, &motifIntValue );
  212.     XtGetValues( _slider, wargs, 1 );
  213.  
  214.     return( convertSliderToFloat( motifIntValue ));
  215. }
  216.  
  217. float 
  218. NoodleSlider::getMin()
  219. {
  220.     if ( _slider == NULL )
  221.     return 0.0;
  222.  
  223.     Arg wargs[10];
  224.     int motifIntValue;
  225.  
  226.     XtSetArg( wargs[0], XmNminimum, &motifIntValue );
  227.     XtGetValues( _slider, wargs, 1 );
  228.  
  229.     return( convertSliderToFloat( motifIntValue ));
  230. }
  231.  
  232.  
  233. float 
  234. NoodleSlider::getMax()
  235. {
  236.     if ( _slider == NULL )
  237.     return 0.0;
  238.  
  239.     Arg wargs[10];
  240.     int motifIntValue;
  241.  
  242.     XtSetArg( wargs[0], XmNmaximum, &motifIntValue );
  243.     XtGetValues( _slider, wargs, 1 );
  244.  
  245.     return( convertSliderToFloat( motifIntValue ));
  246. }
  247.  
  248. short
  249. NoodleSlider::getNumDecimals()
  250. {
  251.     if (_slider == NULL)
  252.     return 0;
  253.     Arg wargs[10];
  254.     short decimals;
  255.     
  256.     XtSetArg( wargs[0], XmNdecimalPoints, &decimals);
  257.     XtGetValues( _slider, wargs, 1 );
  258.  
  259.     return decimals;
  260. }
  261.  
  262. float
  263. NoodleSlider::convertSliderToFloat( int sliderValue )
  264. {
  265.     short decimals;
  266.     float theVal;
  267.     int   count;
  268.  
  269.     /* shift over the appropriate number of decimal places */
  270.     decimals = getNumDecimals();
  271.     if (decimals < 0)
  272.     decimals = 0;
  273.     for( count = 0, theVal = sliderValue; count < decimals; count++ )
  274.     theVal /= 10.0;
  275.  
  276.     return( theVal );
  277. }
  278.  
  279. int
  280. NoodleSlider::convertFloatToSlider( float floatValue )
  281. {
  282.     short decimals;
  283.     float convertedFloat;
  284.     int   count, returnValue;
  285.  
  286.     /* shift over the appropriate number of decimal places */
  287.     decimals = getNumDecimals();
  288.  
  289.     if (decimals < 0)
  290.     decimals = 0;
  291.     for( count = 0, convertedFloat = floatValue; count < decimals; count++ )
  292.     convertedFloat *= 10.0;
  293.     returnValue = (int) convertedFloat;
  294.     return( returnValue );
  295. }
  296.  
  297.  
  298. void
  299. NoodleSlider::valueWidgetCallback( Widget, void *client_data, void *)
  300. {
  301.     float    theVal;
  302.     NoodleSlider *theNdlSlider = (NoodleSlider *) client_data;
  303.     Arg wargs[10];
  304.     char *valString;
  305.  
  306.     if (theNdlSlider && theNdlSlider->_value ) {
  307.     // get text value from the label 
  308.     XtSetArg( wargs[0], XmNvalue, &valString );
  309.     XtGetValues( theNdlSlider->_value, wargs, 1 );
  310.     if ( sscanf( valString, "%f", &theVal ) ) {
  311.         // set the value throughout the NoodleSlider
  312.         theNdlSlider->setValue( theVal );
  313.     }
  314.     theNdlSlider->valueChangedCallbacks->invokeCallbacks(theNdlSlider);
  315.     }
  316. }
  317. void
  318. NoodleSlider::sliderWidgetCallback( Widget, void *client_data, void *)
  319. {
  320.     float theVal;
  321.     NoodleSlider *theNdlSlider = (NoodleSlider *) client_data;
  322.  
  323.     // Get the value from the slider
  324.     theVal = theNdlSlider->getValue();
  325.  
  326.     theNdlSlider->setValue(theVal);
  327.  
  328.     theNdlSlider->valueChangedCallbacks->invokeCallbacks(theNdlSlider);
  329. }
  330.  
  331. void 
  332. NoodleSlider::addValueChangedCallback(SoCallbackListCB *f, void *userData )
  333. { valueChangedCallbacks->addCallback( f, userData ); }
  334.  
  335. void 
  336. NoodleSlider::removeValueChangedCallback(SoCallbackListCB *f, void *userData )
  337. { valueChangedCallbacks->removeCallback( f, userData ); }
  338.  
  339.  
  340.